#include "monitor_device_res.h"

// 获取CPU使用率
double get_cpu_usage()
{
    static unsigned long long last_total = 0, last_idle = 0;
    unsigned long long total = 0, idle = 0;
    double usage = 0.0;
    
    FILE *fp = fopen("/proc/stat", "r");
    if (fp == NULL) {
        perror("fopen /proc/stat failed");
        return -1.0;
    }
    
    char line[256];
    if (fgets(line, sizeof(line), fp) == NULL) 
    {
        fclose(fp);
        return -1.0;
    }
    fclose(fp);
    
    // 解析/proc/stat的第一行（CPU总信息）
    char cpu[10];
    unsigned long long user, nice, system, idle_time, iowait, irq, softirq, steal, guest, guest_nice;
    sscanf(line, "%s %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu", 
           cpu, &user, &nice, &system, &idle_time, &iowait, &irq, &softirq, &steal, &guest, &guest_nice);
    
    // 计算总CPU时间
    total = user + nice + system + idle_time + iowait + irq + softirq + steal;
    idle = idle_time;
    
    // 如果是第一次调用，初始化last值
    if (last_total == 0 || last_idle == 0) 
    {
        last_total = total;
        last_idle = idle;
        return 0.0;
    }
    
    // 计算CPU使用率
    unsigned long long total_diff = total - last_total;
    unsigned long long idle_diff = idle - last_idle;
    
    if (total_diff > 0) 
    {
        usage = 100.0 * (total_diff - idle_diff) / total_diff;
    }
    
    // 更新上一次的值
    last_total = total;
    last_idle = idle;
    
    return usage;
}

// 获取内存使用信息
void get_memory_info(unsigned long long *total, unsigned long long *free, unsigned long long *available)
{
    FILE *fp = fopen("/proc/meminfo", "r");
    if (fp == NULL) 
    {
        perror("fopen /proc/meminfo failed");
        return;
    }
    
    char line[256];
    while (fgets(line, sizeof(line), fp)) 
    {
        if (strstr(line, "MemTotal:") != NULL) 
        {
            sscanf(line, "MemTotal: %llu kB", total);
        } 
        else if (strstr(line, "MemFree:") != NULL) 
        {
            sscanf(line, "MemFree: %llu kB", free);
        } 
        else if (strstr(line, "MemAvailable:") != NULL) 
        {
            sscanf(line, "MemAvailable: %llu kB", available);
        }
    }

    fclose(fp);
}

// 获取系统运行时间
double get_uptime()
{
    FILE *fp = fopen("/proc/uptime", "r");
    if (fp == NULL) {
        perror("fopen /proc/uptime failed");
        return -1.0;
    }
    
    double uptime, idle_time;
    fscanf(fp, "%lf %lf", &uptime, &idle_time);
    fclose(fp);
    
    return uptime;
}

// 获取负载平均值
void get_load_average(double *load1, double *load5, double *load15)
{
    FILE *fp = fopen("/proc/loadavg", "r");
    if (fp == NULL) {
        perror("fopen /proc/loadavg failed");
        return;
    }
    
    fscanf(fp, "%lf %lf %lf", load1, load5, load15);
    fclose(fp);
}

// 格式化时间
void format_uptime(double seconds, char *buffer, size_t size)
{
    int days = seconds / (24 * 3600);
    int hours = (int)(seconds) % (24 * 3600) / 3600;
    int minutes = (int)(seconds) % 3600 / 60;
    int secs = (int)seconds % 60;
    
    if (days > 0) {
        snprintf(buffer, size, "%d天 %02d:%02d:%02d", days, hours, minutes, secs);
    } else {
        snprintf(buffer, size, "%02d:%02d:%02d", hours, minutes, secs);
    }
}

void get_device_res(char *cpu_usage_double_buf, 
                        char *cpu_usage_int_buf, 
                        char *mem_total_buf, 
                        char *mem_use_buf, 
                        char *mem_usage_buf, 
                        int *mem_usage_int, 
                        char *system_runtime_buf, 
                        char *load1_buf, 
                        double *load1_value, 
                        char *load5_buf, 
                        char *load15_buf)
{
    // printf("=== 系统资源监控 ===\n");
    
    // 获取CPU使用率
    double cpu_usage = get_cpu_usage();
    if (cpu_usage >= 0) 
    {
        // printf("CPU使用率: %.2f%%\n", cpu_usage);

        sprintf(cpu_usage_double_buf, "%.2f", cpu_usage);
        sprintf(cpu_usage_int_buf, "%d", (int)cpu_usage);
    }
    
    // 获取内存信息
    unsigned long long mem_total = 0, mem_free = 0, mem_available = 0;
    get_memory_info(&mem_total, &mem_free, &mem_available);
    
    if (mem_total > 0) 
    {
        double mem_used_percent = 100.0 * (mem_total - mem_available) / mem_total;
        // printf("内存使用情况:\n");
        // printf("  总内存: %.2f MB\n", mem_total / 1024.0);
        // printf("  可用内存: %.2f MB\n", mem_available / 1024.0);
        // printf("  内存使用率: %.2f%%\n", mem_used_percent);

        // 更新各个字符串
        sprintf(mem_total_buf, "%.2f", mem_total / 1024.0);
        sprintf(mem_use_buf, "%.2f", mem_available / 1024.0);
        sprintf(mem_usage_buf, "%.2f%%", mem_used_percent);
        *mem_usage_int=(int)mem_used_percent;
        // printf("mem_usage_int:%d\n",mem_usage_int);
    }

   
    // 获取系统运行时间
    double uptime = get_uptime();
    if (uptime >= 0) 
    {
        char uptime_str[64];
        format_uptime(uptime, uptime_str, sizeof(uptime_str));
        // printf("系统运行时间: %s\n", uptime_str);

        // 更新字符串
        sprintf(system_runtime_buf, "%s", uptime_str);
    }


    // 获取负载平均值
    double load1, load5, load15;
    get_load_average(&load1, &load5, &load15);
    // printf("系统负载: %.2f (1分钟), %.2f (5分钟), %.2f (15分钟)\n", load1, load5, load15);

    // 更新各个字符串
    sprintf(load1_buf, "%.2f", load1);
    sprintf(load5_buf, "%.2f", load5);
    sprintf(load15_buf, "%.2f", load15);
    *load1_value=load1;
    // printf("load1_value:%.2f\n",load1_value);
    
    // printf("===================\n");
    
    // // 创建JSON格式的输出
    // cJSON *root = cJSON_CreateObject();
    
    // if (cpu_usage >= 0) 
    // {
    //     cJSON_AddNumberToObject(root, "cpu_usage", cpu_usage);
    // }
    
    // if (mem_total > 0) 
    // {
    //     cJSON_AddNumberToObject(root, "mem_total_mb", mem_total / 1024.0);
    //     cJSON_AddNumberToObject(root, "mem_available_mb", mem_available / 1024.0);
    //     cJSON_AddNumberToObject(root, "mem_usage_percent", 100.0 * (mem_total - mem_available) / mem_total);
    // }
    
    // if (uptime >= 0) {
    //     char uptime_str[64];
    //     format_uptime(uptime, uptime_str, sizeof(uptime_str));
    //     cJSON_AddStringToObject(root, "uptime", uptime_str);
    // }
    
    // cJSON_AddNumberToObject(root, "load1", load1);
    // cJSON_AddNumberToObject(root, "load5", load5);
    // cJSON_AddNumberToObject(root, "load15", load15);
    
    // // 输出JSON
    // char *json_str = cJSON_Print(root);
    // printf("\nJSON格式输出:\n%s\n", json_str);
    
    // 清理
    // free(json_str);
    // cJSON_Delete(root);
}
